<template>
  <view class="vm-page vh">
    <view class="dev-detail">
      <!-- 服务信息 -->
      <view class="dev-info">
        <nut-row>
          <nut-col :span="20">
            <view class="dev-name">Service UUID ：</view>
            <view class="dev-servId">{{ editConf.servId || "" }}</view>
            <view class="dev-name">Characteristic UUID ：</view>
            <view class="dev-charId">{{ editConf.charId || "" }}</view>
            <view class="dev-name">Properties ：</view>
            <view class="dev-charId"
              >Read: {{ editConf.props.read ? "Yes" : "No" }} Write:
              {{ editConf.props.write ? "Yes" : "No" }} Notify:
              {{ editConf.props.notify ? "Yes" : "No" }}</view
            >
          </nut-col>
          <nut-col :span="4">
            <view class="dev-connect">
              {{ connectStatusText }}
            </view>
          </nut-col>
        </nut-row>
      </view>

      <!-- 日志区 -->
      <view class="dev-log">
        <view class="log-tip" v-if="logs.length == 0">命令记录区</view>
        <view class="log-container" v-else>
          <view class="log-line" v-for="log in logs" :key="log.time">
            <view class="line-time">{{ timeText(log.time) }}</view>
            <view class="line-type">{{ log.type }}</view>
            <view class="line-value">{{ log.value }}</view>
          </view>
        </view>
      </view>

      <!-- 操作区 -->
      <view class="dev-editpanel">
        <nut-tabs v-model="tabVal">
          <nut-tabpane title="LuatOS Demo指令">
            <view
              class="cmd-demo"
              v-for="(demo, idx) in demoList"
              :key="demo.title"
            >
              <!-- <view class="demo-title">{{ demo.title }}</view>
              <view class="demo-desc">{{ demo.desc }}</view> -->
              <nut-cell
                :title="demo.title"
                :desc="demo.desc"
                is-link
                @tap="showDemoMenu(demo, idx)"
              ></nut-cell>
            </view>
          </nut-tabpane>
          <nut-tabpane title="手动输入指令">
            <view class="cmd-input">
              <nut-textarea
                v-model="cmdText"
                :placeholder="canWrite ? '请输入指令（hex）' : '不支持输入指令'"
                limit-show
                rows="1"
                :disabled="!canWrite"
                max-length="20"
              />
            </view>
            <view class="cmd-btn">
              <nut-button
                type="primary"
                block
                plain
                @tap="sendManualCmd"
                :disabled="!canSend"
                >{{ canWrite ? "发送命令" : "发送命令（禁用）" }}</nut-button
              >
            </view>
          </nut-tabpane>
        </nut-tabs>
      </view>

      <!-- 弹出层 -->
      <nut-actionsheet
        v-model:visible="demo0Visible"
        @close="switchDemoMenu(0)"
        :menu-items="demoList[0].cmds"
        @choose="chooseDemoMenu"
        cancel-txt="取消"
      ></nut-actionsheet>

      <!-- demo输入-->
      <nut-popup
        position="bottom"
        closeable
        close-icon-position="top-right"
        :close-on-click-overlay="true"
        :style="{ height: '50%' }"
        v-model:visible="demo0Pop"
        :close="hideNimblePopInput"
        :click-overlay="hideNimblePopInput"
        :click-close-icon="hideNimblePopInput"
      >
        <view class="cmd-poppanel">
          <view class="cmd-input">
            <nut-textarea
              v-model="demo0Text"
              :placeholder="
                canWrite ? '请输入显示内容（支持中文）' : '不支持输入'
              "
              limit-show
              rows="1"
              :disabled="!canWrite"
              max-length="20"
            />
          </view>
          <view class="cmd-btn">
            <nut-button
              type="primary"
              block
              plain
              @tap="sendNimbleCmd"
              :disabled="!canSend"
              >{{ canWrite ? "发送内容" : "发送内容（禁用）" }}</nut-button
            >
          </view>
        </view>
      </nut-popup>
    </view>
  </view>
</template>

<script lang="ts">
import Taro from "@tarojs/taro";
import { get } from "@/utils/storage";
import { BTManager, ConnectStatus } from "@/components/wx-ant-ble/index";
const formatNumber = (n) => {
  n = n.toString();
  return n[1] ? n : "0" + n;
};

const strToHexCharCode = (str = "") => {
  if (str === "") return "";
  var hexCharCode = [];
  // hexCharCode.push("0x");
  str = encodeURI(str);
  for (var i = 0; i < str.length; i++) {
    hexCharCode.push(str.charCodeAt(i).toString(16));
  }
  return hexCharCode.join("");
};

export default {
  name: "Index",
  components: {},
  data() {
    return {
      dev: {},
      editConf: {
        props: {},
      },
      connectStatus: -1,
      logs: [],
      tabVal: "0",
      sending: false,
      // 手动
      cmdText: "",
      // demo
      demo0Visible: false,
      demo0Pop: false,
      demo0Text: "",
      demoList: [
        {
          title: "nimble",
          desc: "控制三色灯，显示文字",
          cmds: [
            {
              name: "显示英文字符",
              func: "showNimbleText",
              param: "hello",
            },
            {
              name: "显示中文字符",
              func: "showNimbleText",
              param: "你好",
            },
            {
              name: "显示自定义字符",
              func: "showNimblePopInput",
            },
            {
              name: "【蓝灯】点亮",
              value: "6c65642c612c6f6e",
            },
            {
              name: "【绿灯】点亮",
              value: "6c65642c622c6f6e",
            },
            {
              name: "【红灯】点亮",
              value: "6c65642c632c6f6e",
            },
            {
              name: "【蓝灯】关闭",
              value: "6c65642c612c6f6666",
            },
            {
              name: "【绿灯】关闭",
              value: "6c65642c622c6f6666",
            },
            {
              name: "【红灯】关闭",
              value: "6c65642c632c6f6666",
            },
          ],
        },
      ],
      // btManager
      bt: null,
    };
  },
  computed: {
    canWrite() {
      return this.editConf.props.write == true;
    },
    canSend() {
      return this.canWrite & (this.cmdText.length > 0);
    },
    connectStatusText() {
      if (this.connectStatus == 0) {
        return "未连接";
      }
      if (this.connectStatus == 1) {
        return "正在连接..";
      }
      if (this.connectStatus == 2) {
        return "已连接";
      }
      return "状态未知";
    },
  },
  methods: {
    initBluetooth() {
      console.log("init-editor");
      // 初始化蓝牙管理器
      this.bt = new BTManager({
        debug: true,
      });
      this.connectStatus = this.bt.connectStatus;
      // 注册状态回调
      let self = this;
      this.bt.registerDidUpdateConnectStatus((res) => {
        console.log("editor registerDidUpdateConnectStatus", res);
        self.connectStatus = res.connectStatus;
        if (res.connectStatus === ConnectStatus.disconnected) {
          Taro.showToast({
            title: res.message,
            icon: "none",
            duration: 2000,
          });
        }
      });

      this.bt.registerDidUpdateValueForCharacteristic(
        this.didUpdateValueForCharacteristic.bind(this)
      );
    },
    didUpdateValueForCharacteristic(res) {
      console.log(
        "characteristic registerDidUpdateValueForCharacteristic",
        res
      );
      this.addCmdLog(res.value, "R");
    },
    sendManualCmd() {
      if (this.sending) {
        return;
      }
      this.addCmdLog(this.cmdText, "W");
      this.cmdText = "";
    },
    sendDemoCmd(cmdText) {
      if (this.sending) {
        return;
      }
      this.addCmdLog(cmdText, "W");
    },
    addCmdLog(cmdText, type) {
      let logs = this.logs;
      logs.unshift({
        time: new Date().getTime(),
        type,
        value: cmdText,
      });
      this.logs = logs;
      if (type == "W") {
        this.realSendCmd(cmdText);
      }
    },
    realSendCmd(cmdText) {
      this.sending = true;
      this.bt
        .write({
          suuid: this.editConf.servId,
          cuuid: this.editConf.charId,
          value: cmdText,
        })
        .then((res) => {
          console.log("characteristic write", res);
          this.sending = false;
        })
        .catch((e) => {
          console.log("characteristic write", e);
          this.sending = false;
        });
    },
    timeText(time) {
      let td = new Date(time);
      const hour = td.getHours();
      const minute = td.getMinutes();
      const second = td.getSeconds();
      return [hour, minute, second].map(formatNumber).join(":");
    },
    showDemoMenu(demo, index) {
      this.switchDemoMenu(index);
    },
    switchDemoMenu(index) {
      let k = `demo${index}Visible`;
      this[k] = !this[k];
    },
    chooseDemoMenu(item, index) {
      this.switchDemoMenu(index);
      // 执行命令
      if (item.func) {
        let func = this[item.func];
        if (func) {
          func(item.param);
        }
      }
      // 直接发送内容
      else {
        this.sendDemoCmd(item.value);
      }
    },
    showNimblePopInput() {
      this.demo0Pop = true;
    },
    hideNimblePopInput() {
      this.demo0Pop = false;
      this.demo0Text = "";
    },
    showNimbleText(text) {
      let cmdText = "646973706c61792c" + strToHexCharCode(text);
      this.sendDemoCmd(cmdText);
    },
    sendNimbleCmd() {
      let cmdText = "646973706c61792c" + strToHexCharCode(this.demo0Text);
      this.sendDemoCmd(cmdText);
      this.hideNimblePopInput();
    },
  },
  mounted() {
    let device = get("curr_bledev") || null;
    if (device) {
      this.dev = device;
    }
    let editConf = get("curr_bleedit") || null;
    if (editConf) {
      this.editConf = editConf;
    }
  },
  onReady() {},
  onShow() {
    this.initBluetooth();
  },
  onHide() {},
  unmounted() {},
  destroyed() {},
  beforedestroy() {},
};
</script>

<style lang="scss">
.dev-info {
  padding: 20px 10px;

  .dev-name {
    font-size: 16px;
  }
  .dev-servId,
  .dev-charId {
    font-size: 12px;
    color: #aaa;
  }
  .dev-connect {
    font-size: 14px;
    color: #1d2088;
    text-align: right;
  }

  background: #efefef;
}

.dev-data {
  padding: 10px 10px;
}

.dev-log {
  background: #b2b5f8d3;
  color: #333;
  width: 100%;
  height: 30vh;
  overflow: auto;
  padding: 10px;

  .log-tip {
    text-align: center;
    padding-top: 30px;
    color: #333;
  }

  .log-container {
  }

  .log-line {
    font-size: 12px;
    padding-bottom: 5px;
    .line-time {
      display: inline-block;
      width: 55px;
      color: #333;
    }
    .line-type {
      display: inline-block;
      width: 18px;
      color: #080;
    }
    .line-value {
      display: inline-block;
      color: #b60000;
    }
  }

  .log-clear-btn {
    padding: 10px 0;
  }
}

.cmd-poppanel {
  padding-top: 50px;
  padding-left: 10px;
  padding-right: 10px;
}

.cmd-input {
  border: 1px solid #efefef;

  textarea {
    min-height: 70px;
    height: 70px;
  }
}
.cmd-btn {
  padding: 15px 0 0 20px;
}

.cmd-demo {
  padding: 10px;

  .demo-title {
    font-size: 16px;
  }
  .demo-desc {
    font-size: 12px;
    color: #aaa;
  }
  .demo-btns {
    padding: 5px 0;
  }
  .demo-btn {
    padding: 10px 0;
    border: 1px solid #acacac;
    background: #acacac;
    color: #1d2088;
    text-align: center;
    border-radius: 2px;
    margin-bottom: 5px;
  }
}

// fix
.nut-tabpane {
  padding: 10px;
}
</style>
